package io.sage.ch06.simplifymethodcall;

/**
 * 10.4 Separate Query from Modifier 将查询函数和修改函数分离
 * <p>
 * 问题场景：某个函数既返回对象状态值，又修改对象状态
 * 重构思路：建立两个不同的函数，其中一个负责查询，另一个负责修改。
 * 做法：
 * 1）新建一个查询函数，另它返回的值与原函数相同。
 * 2）修改原函数，令它调用查询函数，并返回获得的结果。如：每个return语句都改为：return newQuery();
 * 3）编译，测试
 * 4）将调用原函数的代码改为调用查询函数。然后，再调用查询函数的那一行之前，加上对原函数的调用。每次修改后，编译测试。
 * 5）将原函数的返回值改为void，并删除其中所有的return语句。
 */
public class SeparateQueryFromModifier {

    private void sendAlert() {
    }

    private void someLaterCode(String found) {
    }

    /**
     * 重构前
     * 查询动作和修改动作合在一起
     */
    String foundMiscreant(String[] people) {
        for (int i = 0; i < people.length; i++) {
            if (people[i].equals("Don")) {
                sendAlert();
                return "Don";
            }
            if (people[i].equals("John")) {
                sendAlert();
                return "John";
            }
        }
        return "";
    }

    /**
     * 重构前
     * 方法调用者
     */
    void checkSecurity(String[] people) {
        String found = foundMiscreant(people);
        someLaterCode(found);
    }

    /**
     * 重构后
     * 独立查询动作
     */
    String foundPerson(String[] people) {
        for (int i = 0; i < people.length; i++) {
            if (people[i].equals("Don")) {
                return "Don";
            }
            if (people[i].equals("John")) {
                return "John";
            }
        }
        return "";
    }

    /**
     * 重构后
     * 独立修改动作
     * 注意使用Substitute Algorithm，减少查询函数和修改函数的重复代码
     */
    void sendAlert(String[] people) {
        if (!foundPerson(people).equals("")) {
            sendAlert();
        }
    }

    /**
     * 重构后
     * 方法调用者
     */
    void checkSecurity_new(String[] people) {
        foundMiscreant(people);
        String found = foundPerson(people);
        someLaterCode(found);
    }
}
